﻿using AutoMapper;
using Harmontronics.Common;
using Harmontronics.IService;
using Harmontronics.Model.Dto.Login;
using Harmontronics.Model.Dto.Menu;
using Harmontronics.Model.Entitys;
using Harmontronics.Repository;
using Microsoft.IdentityModel.Tokens;
using Org.BouncyCastle.Ocsp;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Harmontronics.Service
{
    public class MenuService : IMenuService
    {
        private readonly IMapper _mapper;
        private HcDbContext _db { get; set; }
        private readonly IUnitOfWork _unitOfWork;

        public MenuService(IUnitOfWork unitOfWork, IMapper mapper, HcDbContext db)
        {
            _mapper = mapper;
            _db = db;
            _unitOfWork = unitOfWork;
        }

        #region 递归查询
        /// <summary>
        /// 部分信息递归（登录后动态路由
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="objMenu"></param>
        /// <returns></returns>
        private List<DynamicRoutes> GetroutesByParentId(int parentId, List<Menu> objMenu)
        {
            List<DynamicRoutes> routelist = new List<DynamicRoutes>();
            List<Menu> rootMenu = objMenu.Where(i => i.ParentId == parentId).ToList();
            rootMenu = rootMenu.OrderBy(i => i.MenuSort).ToList();
            foreach (var menu in rootMenu)
            {
                //获取role的dis
                List<string> rolesDes = new List<string>();
                List<MenuRoleRelation> relations = _db.MenuRoleRelation.Where(i => i.MenuId == menu.Id).ToList();
                foreach (var rela in relations)
                {
                    Role role = _db.Roles.SingleOrDefault(i => i.Id == rela.RoleId);
                    if(role == null)
                    {
                        continue;
                    }
                    rolesDes.Add(role.RoleName);
                }

                DynamicRoutes newRoute = new DynamicRoutes
                {
                    path = menu.Path,
                    component = menu.Url,
                    redirect = menu.Redirect,
                    name = menu.Name,
                    meta = new Meta
                    {
                        title = menu.Title,
                        elIcon = menu.ElIcon,
                        roles = rolesDes.ToArray(),
                        alwaysShow = menu.AlwaysShow,
                        keepAlive = menu.KeepAlive
                    }


                };
                if (objMenu.Where(i => i.ParentId == menu.Id).ToList().Count > 0)
                {
                    newRoute.Children = GetroutesByParentId(menu.Id, objMenu);
                }
                else
                {
                    newRoute.Children = null;
                }
                routelist.Add(newRoute);
            }
            return routelist;
        }
        /// <summary>
        /// 全部信息递归
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="objMenu"></param>
        /// <returns></returns>
        private List<ShowDynamicRoutes> ShowroutesByParentId(int parentId, List<Menu> objMenu)
        {
            List<ShowDynamicRoutes> routelist = new List<ShowDynamicRoutes>();
            List<Menu> rootMenu = objMenu.Where(i => i.ParentId == parentId).ToList();
            rootMenu = rootMenu.OrderBy(i => i.MenuSort).ToList();
            foreach (var menu in rootMenu)
            {
                //获取role的dis
                List<string> rolesDes = new List<string>();
                List<MenuRoleRelation> relations = _db.MenuRoleRelation.Where(i => i.MenuId == menu.Id).ToList();
                foreach (var rela in relations)
                {
                    Role role = _db.Roles.SingleOrDefault(i => i.Id == rela.RoleId);
                    rolesDes.Add(role.RoleName);
                }

                ShowDynamicRoutes newRoute = new ShowDynamicRoutes
                {
                    id = menu.Id,
                    parentId = menu.ParentId,
                    title = menu.Title,
                    elIcon = menu.ElIcon,
                    menuType = menu.MenuType,
                    menuSort = menu.MenuSort,
                    keepAlive = menu.KeepAlive,
                    createTime = menu.CreateTime,
                    updateTime = menu.UpdateTime,
                    createBy = menu.CreateBy,
                    updateBy = menu.UpdateBy,
                    enable = menu.Enable,
                    alwaysShow = menu.AlwaysShow,
                    path = menu.Path,
                    url = menu.Url,
                    redirect = menu.Redirect,
                    name = menu.Name,

                };
                if (objMenu.Where(i => i.ParentId == menu.Id).ToList().Count > 0)
                {
                    newRoute.Children = ShowroutesByParentId(menu.Id, objMenu);
                }
                else
                {
                    newRoute.Children = null;
                }
                routelist.Add(newRoute);
            }
            return routelist;
        }

        #endregion

        /// <summary>
        /// 获取动态路由
        /// </summary>
        /// <returns></returns>
        public List<DynamicRoutes> GetAllMenus()
        {

            List<Menu> objMenu = _db.Menu.ToList();

            return GetroutesByParentId(0, objMenu);
        }
        /// <summary>
        /// 获取全部数据
        /// </summary>
        /// <param name="getData"></param>
        /// <returns></returns>
        public List<ShowDynamicRoutes> GetAllMenus(MenuGet getData)
        {
            List<Menu> objMenu = _db.Menu.ToList();
            if (getData.enable.Length > 0)
            {
                if (getData.enable == "True" || getData.enable == "true" || getData.enable == "1")
                {
                    objMenu = objMenu.Where(i => i.Enable == 1).ToList();
                }
                else
                {
                    objMenu = objMenu.Where(i => i.Enable == 0).ToList();
                }
            }
            if (getData.menuName.Length > 0)
            {
                objMenu = objMenu.Where(i => i.Title.Contains(getData.menuName)).ToList();
                //补充其父级
                objMenu = RepParentMenu(0,objMenu);
                
            }

            return ShowroutesByParentId(0, objMenu);
        }

        private List<Menu> RepParentMenu(int i ,List<Menu> objMenu)
        {
            while(i < objMenu.Count)
            {
                Menu menu = objMenu[i++];
                if (menu.ParentId > 0)
                {
                    Menu parMenu = objMenu.SingleOrDefault(i => i.Id == menu.ParentId);
                    if (parMenu == null)
                    {
                        parMenu = _db.Menu.SingleOrDefault(i => i.Id == menu.ParentId);
                        if (parMenu != null)
                        {
                            objMenu.Add(parMenu);
                            return RepParentMenu(i, objMenu);
                        }
                    }
                }
            }
            return objMenu;
        }

        /// <summary>
        /// 根据id获取动态路由
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<DynamicRoutes> GetMenusByEmployeeNumber(int userId)
        {
            UserRoleRelation userRoleRelation = _db.UserRoleRelation!.Where(i => i.UserId == userId).FirstOrDefault();
            if (userRoleRelation == null)
            {
                return new List<DynamicRoutes>();
            }
            List<MenuRoleRelation> menusRoleList = _db.MenuRoleRelation!.Where(i => i.RoleId == userRoleRelation.RoleId).ToList();
            List<Menu> menus = _db.Menu!.ToList();
            List<Menu> objMenu = new List<Menu>();
            foreach (var menuRoleRelation in menusRoleList)
            {
                if (menuRoleRelation.MenuId != null)
                {
                    objMenu.Add(menus.SingleOrDefault(i => i.Id == menuRoleRelation.MenuId));
                }
            }
            return GetroutesByParentId(0, objMenu);
        }
        /// <summary>
        /// 增
        /// </summary>
        /// <param name="menuAdd"></param>
        /// <returns></returns>
        public bool AddMenu(MenuAdd menuAdd)
        {
            try
            {
                Menu menu = _mapper.Map<Menu>(menuAdd);
                menu.CreateTime = DateTime.Now;
                _db.Menu.Add(menu);
                //_db.SaveChanges();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        public bool UpdateMenu(MenuEdit menuEdit)
        {
            try
            {
                Menu menu = _db.Menu.SingleOrDefault(i => i.Id == menuEdit.Id);
                _mapper.Map(menuEdit, menu);
                menu.UpdateTime = DateTime.Now;
                _db.Menu.Update(menu);
                //_db.SaveChanges();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
        public bool DeleteMenuById(int id)
        {
            try
            {
                Menu menu = _db.Menu.SingleOrDefault(i => i.Id == id);
                List<MenuRoleRelation> relations = _db.MenuRoleRelation.Where(i => i.MenuId == id).ToList();
                if (menu != null)
                {
                    _db.Menu.Remove(menu);
                    _db.MenuRoleRelation.RemoveRange(relations);
                    //_db.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
        public bool BatchDelMenu(List<int> ids)
        {
            try
            {
                List<Menu> entities = _db.Menu.Where(i => ids.Contains(i.Id)).ToList();
                List<MenuRoleRelation> relations = _db.MenuRoleRelation.Where(i => ids.Contains((int)i.MenuId)).ToList();
                if (entities.Count > 0)
                {
                    _db.Menu.RemoveRange(entities);
                    _db.MenuRoleRelation.RemoveRange(relations);
                }
                //_db.SaveChanges();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        public List<ShowDynamicRoutes> GetAllMenusByRoleId(int roleId)
        {
            List<MenuRoleRelation> Relation = _db.MenuRoleRelation.Where(i => i.RoleId == roleId).ToList();
            List<Menu> objMenu = new List<Menu>();
            foreach (MenuRoleRelation relation in Relation)
            {
                var obj = _db.Menu.SingleOrDefault(i => i.Id == relation.MenuId);
                if (obj != null)
                {
                    objMenu.Add(obj);
                }
            }

            return ShowroutesByParentId(0, objMenu);
        }

        public List<ShowDynamicRoutes> GetAllAbleMenus()
        {

            List<Menu> objMenu = _db.Menu.Where(i => i.Enable == 1).ToList();

            return ShowroutesByParentId(0, objMenu);
        }

        public List<int> CollectMenuIds(List<int> ids, List<ShowDynamicRoutes> shows)
        {
            foreach (ShowDynamicRoutes showMenu in shows)
            {
                ids.Add(showMenu.id);
                if (!showMenu.Children.IsNullOrEmpty())
                {
                    ids = CollectMenuIds(ids, showMenu.Children);
                }
            }
            return ids;
        }

        public Menu GetMenuById(int id)
        {
            Menu menu;
            try
            {
                menu = _db.Menu.SingleOrDefault(i => i.Id == id);
            }
            catch (Exception ex)
            {
                return null;
            }
            return menu;
        }

    }
}
